Skip to content

fix(identity): copy loadAudiusSdk.cjs into build output#14474

Merged
dylanjeffers merged 2 commits into
mainfrom
claude/identity-service-missing-module-mb6xo2
Jun 15, 2026
Merged

fix(identity): copy loadAudiusSdk.cjs into build output#14474
dylanjeffers merged 2 commits into
mainfrom
claude/identity-service-missing-module-mb6xo2

Conversation

@dylanjeffers

Copy link
Copy Markdown
Contributor

Problem

The identity-service pod crashes on startup with:

Error: Cannot find module '/app/packages/identity-service/build/loadAudiusSdk.cjs'
Require stack:
- /app/packages/identity-service/build/src/index.js

Root cause

The production container runs the compiled entrypoint node build/src/index.js (scripts/start.sh). That file requires the SDK loader via a path relative to __dirname:

const { loadAudiusSdk } = require(
  path.join(__dirname, '..', 'loadAudiusSdk.cjs')
)

The .. resolves differently depending on where the entrypoint physically lives:

  • Dev (ts-node-dev runs src/index.ts): __dirname = identity-service/src → resolves to package-root loadAudiusSdk.cjs
  • Prod (node runs build/src/index.js): __dirname = identity-service/build/src → resolves to build/loadAudiusSdk.cjs

loadAudiusSdk.cjs deliberately lives outside src/ as a plain .cjs file (so ts-node-dev doesn't transpile its import() into require() and trigger ERR_REQUIRE_ESM). Because it isn't a .ts file, tsc never emits it into build/, and the copyfiles build step only copied src/emails. So build/loadAudiusSdk.cjs was never present in the production image → MODULE_NOT_FOUND.

Fix

Extend the copyfiles script to also copy loadAudiusSdk.cjs into build/, so the existing relative require('../loadAudiusSdk.cjs') resolves correctly in both dev and prod.

Verification

  • Ran the build + copyfiles locally and confirmed build/loadAudiusSdk.cjs is produced.
  • Confirmed the module loads and exports loadAudiusSdk (a function).

https://claude.ai/code/session_011oMzUJoMTNRaGUh7qPt1jp


Generated by Claude Code

The production container runs the compiled entrypoint at
build/src/index.js, which requires '../loadAudiusSdk.cjs' relative to
__dirname (resolving to build/loadAudiusSdk.cjs). Because
loadAudiusSdk.cjs lives outside src/ as a plain .cjs file, tsc never
emits it into build/, and the copyfiles step only copied src/emails.
This caused MODULE_NOT_FOUND at startup in prod.

Copy loadAudiusSdk.cjs into build/ during the build so the relative
require resolves in both dev (ts-node-dev) and prod (compiled).
@changeset-bot

changeset-bot Bot commented Jun 15, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: e7658a2

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@socket-security

socket-security Bot commented Jun 15, 2026

Copy link
Copy Markdown

Dependency limit exceeded — report not shown.

This pull request scan exceeded the 10,000-dependency limit applied to this scan, so the results are incomplete and may be inaccurate. To avoid reporting false positives, Socket has not posted a report.

Upgrade your plan to raise the dependency limit and get complete reports, or view the partial scan in the dashboard.

Socket is always free for open source. If this is a non-commercial open source project, contact us to request a free Team account.

src/utils/disposableEmail.js reads src/data/disposable_email_blocklist.conf
at runtime via fs.readFileSync. tsc does not emit .conf files, and the
copyfiles step only copied src/emails, so build/src/data/ was missing in
the production image. This is a latent ENOENT (the blocklist loads lazily
on the first disposable-email check during signup) from the same email
verification PR as the loadAudiusSdk.cjs issue.

Copy src/data into build/src so the blocklist resolves in prod.
@dylanjeffers dylanjeffers merged commit 2641997 into main Jun 15, 2026
8 checks passed
@dylanjeffers dylanjeffers deleted the claude/identity-service-missing-module-mb6xo2 branch June 15, 2026 17:30
dylanjeffers added a commit that referenced this pull request Jun 16, 2026
…ers -> .users)

authMiddleware backfills blockchainUserId/handle for users whose identity
row lacks them (the state of any guest / freshly signed-up user) by calling
the SDK. It used `req.app.get('audiusSdk').full.users.getUserAccount(...)`,
but the @audius/sdk instance has no `.full` namespace - `users` is a
top-level API. So `.full` is undefined and `.users` throws a synchronous
TypeError ("Cannot read properties of undefined (reading 'users')") on
EVERY new-user auth request (/users/update, /record_ip, etc).

Confirmed in prod logs:
  TypeError: Cannot read properties of undefined (reading 'users')
    at authMiddleware (build/src/authMiddleware.js:97:68)
  msg: "Failed to update blockchainUserId/handle"

The bad accessor came in with the monorepo import (#14388) and only began
firing once #14474 (6/15) made loadAudiusSdk.cjs available so the SDK
actually initialized - matching the signup regression window. The
surrounding try/catch swallowed the error and called next(), so the
backfill silently never happened for new users.

Fix: use the correct accessor `audiusSdk.users.getUserAccount`. Also wrap
the now-live call in a 3s timeout (deferred into a promise so a
missing/misshapen sdk rejects instead of throwing synchronously), so that
once the call actually runs, a slow discovery lookup for a not-yet-indexed
new user degrades gracefully (logged, then next()) instead of stalling auth.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
dylanjeffers added a commit that referenced this pull request Jun 16, 2026
…ers -> .users)

authMiddleware backfills blockchainUserId/handle for users whose identity
row lacks them (the state of any guest / freshly signed-up user) by calling
the SDK. It used `req.app.get('audiusSdk').full.users.getUserAccount(...)`,
but the @audius/sdk instance has no `.full` namespace - `users` is a
top-level API. So `.full` is undefined and `.users` throws a synchronous
TypeError ("Cannot read properties of undefined (reading 'users')") on
EVERY new-user auth request (/users/update, /record_ip, etc).

Confirmed in prod logs:
  TypeError: Cannot read properties of undefined (reading 'users')
    at authMiddleware (build/src/authMiddleware.js:97:68)
  msg: "Failed to update blockchainUserId/handle"

The bad accessor came in with the monorepo import (#14388) and only began
firing once #14474 (6/15) made loadAudiusSdk.cjs available so the SDK
actually initialized - matching the signup regression window. The
surrounding try/catch swallowed the error and called next(), so the
backfill silently never happened for new users.

Fix: use the correct accessor `audiusSdk.users.getUserAccount`.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
dylanjeffers added a commit that referenced this pull request Jun 16, 2026
…ers -> .users) (#14482)

## Problem

Users report failing/janky signups, with `POST
https://identityservice.audius.co/users/update` misbehaving ([Slack
thread](https://audius-internal.slack.com/archives/CA80RCL77/p1781637102823139)).

`authMiddleware` (which gates `/users/update`, `/record_ip`, and every
other authenticated endpoint) backfills `blockchainUserId`/`handle` for
any identity `Users` row that lacks them — i.e. **every guest / freshly
signed-up user**. It did this via:

```js
req.app.get('audiusSdk').full.users.getUserAccount({ ... })
```

But the `@audius/sdk` instance **has no `.full` namespace** — `users` is
a top-level API (`audiusSdk.users.getUserAccount`). So `.full` is
`undefined` and `.users` throws a **synchronous `TypeError`** on every
new-user auth request.

Confirmed in prod logs:

```
TypeError: Cannot read properties of undefined (reading 'users')
    at authMiddleware (build/src/authMiddleware.js:97:68)
msg: "Failed to update blockchainUserId/handle"
```

The surrounding `try/catch` swallowed it and called `next()`, so the
request proceeded but the **backfill silently never happened** — new
identity rows never got `blockchainUserId`/`handle` set.

## Why it started now

The bad accessor came in with the **monorepo import** of
identity-service (#14388, 5/22), which rewrote `authMiddleware` to use
`@audius/sdk`. It was dormant until #14474 (6/15) shipped
`loadAudiusSdk.cjs` into the build, so the SDK actually initialized and
this line began firing — matching the regression window. (identity
hadn't been deployed in a while; 6/15 was the first monorepo image
promoted to prod.)

I verified prod is in the *benign* config otherwise:
`environment=production` is set in `identity-service-secret`, so the SDK
targets prod discovery — the issue is purely the wrong accessor, not SDK
misconfig.

## Fix

Use the correct accessor `audiusSdk.users.getUserAccount` in both
`authMiddleware` and `parameterizedAuthMiddleware`. One-token change per
call site.

## Notes
- Ray's `record_ip` hunch is a red herring: `/users/update` doesn't call
`recordIP`. (Though `/record_ip` is also gated by `authMiddleware`, so
it hit the same TypeError — likely the source of the confusion.)
- Same 6/15 batch also fixed a related latent crash: #14378 reads
`src/data/disposable_email_blocklist.conf` at signup via an unguarded
`fs.readFileSync`; that file wasn't copied into the build until #14474
(same one-liner that also added `loadAudiusSdk.cjs`). Worth hardening
that read separately.
- The batch's endpoint removals (#14458, #14472) are safe — the legacy
`packages/libs` methods that hit them aren't called by any current
client.

## Verification
- Confirmed `getUserAccount` lives on the top-level `UsersApi`
(`audiusSdk.users`) and there is no `.full` in the SDK instance shape
(`@audius/sdk` `index.d.ts`).
- Confirmed response shape `res.data.user` is still correct
(`UserAccountResponse.data: Account`, `Account.user: User`).
- Confirmed prod `environment=production`.

After deploy, the `TypeError ... reading 'users'` log should disappear
and `Failed to update blockchainUserId/handle` should drop to near-zero.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants